#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import json

from common.const import RepositoryDataTypeEnum
from common.parse_parafile import get_env_variable
from generaldb.saphana.comm.saphana_const import SaphanaJsonConstant, SaphanaMetadataKey, SaphanaConst
from saphana.common.saphana_parse_job_param_base import SaphanaParseJobParamsBase


class SaphanaParseBackupParam(SaphanaParseJobParamsBase):
    def __init__(self, pid, job_id, subjob_id):
        super(SaphanaParseBackupParam, self).__init__(pid, job_id, subjob_id)

    def get_sid(self):
        return self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_OBJECT, {}) \
            .get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaJsonConstant.SYSTEM_ID, "")

    def get_system_db_port(self):
        port = self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_ENV, {}) \
            .get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaJsonConstant.SYSTEM_DB_PORT, "")
        if not port:
            port = self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_OBJECT, {}) \
                .get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaJsonConstant.SYSTEM_DB_PORT, "")
        return port

    def get_all_repositories(self):
        return self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.REPOSITORIES, [])

    def get_backup_type(self):
        """
        获取备份类型：全量/增量/差异/日志
        """
        return self._json_param.get(SaphanaJsonConstant.JOB, {}). \
            get(SaphanaJsonConstant.JOB_PARAM, {}).get(SaphanaJsonConstant.BACKUP_TYPE)

    def get_backup_db_name(self):
        """
        获取待备份的数据库名称
        """
        return self._json_param.get(SaphanaJsonConstant.JOB, {}). \
            get(SaphanaJsonConstant.PROTECT_OBJECT, {}).get(SaphanaJsonConstant.NAME, "")

    def get_backup_db_type(self):
        return self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_OBJECT, {}).\
            get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaJsonConstant.DATA_TYPE)

    def get_backup_db_user(self):
        """
        获取待备份的数据库的用户名
        """
        db_type = self.get_backup_db_type()
        # 系统数据库从protectEnv获取
        if db_type == SaphanaConst.SYSTEM_DATABASE:
            user_env = f"{SaphanaJsonConstant.JOB}_{SaphanaJsonConstant.PROTECT_ENV}_{SaphanaJsonConstant.AUTH}_" \
                f"{SaphanaJsonConstant.AUTH_KEY}_{self._pid}"
        # 系统数据库从protectObject获取
        else:
            user_env = f"{SaphanaJsonConstant.JOB}_{SaphanaJsonConstant.PROTECT_OBJECT}_{SaphanaJsonConstant.AUTH}_" \
                f"{SaphanaJsonConstant.AUTH_KEY}_{self._pid}"
        return get_env_variable(user_env)

    def get_backup_db_pwd_env(self):
        db_type = self.get_backup_db_type()
        if db_type == SaphanaConst.SYSTEM_DATABASE:
            return f"job_protectEnv_auth_authPwd_{self._pid}"
        return f"job_protectObject_auth_authPwd_{self._pid}"

    def get_system_db_user(self):
        """
        获取系统数据库自定义参数：当目标数据库为系统数据库时，直接取protectEnv.auth.authKey; 当目标数据库为租户数据库时，取
        protectEnv.auth.extendInfo.auth.authKey
        """
        info_env = f"{SaphanaJsonConstant.JOB}_{SaphanaJsonConstant.PROTECT_ENV}_" \
                   f"{SaphanaJsonConstant.AUTH}_{SaphanaJsonConstant.AUTH_KEY}_{self._pid}"
        return get_env_variable(info_env).strip("\n")

    def get_system_db_pwd(self):
        info_env = f"{SaphanaJsonConstant.JOB}_{SaphanaJsonConstant.PROTECT_ENV}_" \
                   f"{SaphanaJsonConstant.AUTH}_{SaphanaJsonConstant.AUTH_PWD}_{self._pid}"
        return get_env_variable(info_env).strip("\n")

    def get_all_agents_ip(self):
        """
        获取用户选择的所有代理主机的所有IP地址
        例子：”xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx; xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx“
        """
        all_nodes = self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_ENV, {}). \
            get(SaphanaJsonConstant.NODES, [])
        ret_ip_list = []
        for node in all_nodes:
            agent_ip_list_str = node.get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaJsonConstant.AGENT_IP_LIST, "")
            ret_ip_list.append(agent_ip_list_str)
        return ret_ip_list

    def get_all_agents_register_ip(self):
        """
        获取用户选择的所有代理主机注册的IP
        """
        all_nodes = self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_ENV, {}). \
            get(SaphanaJsonConstant.NODES, [])
        ip_list = []
        for node in all_nodes:
            temp_ip = node.get(SaphanaJsonConstant.ENDPOINT, "")
            if not temp_ip:
                continue
            ip_list.append(temp_ip)
        return ip_list

    def get_backup_result(self):
        return self._json_param.get(SaphanaJsonConstant.BACK_JOB_RESULT)

    def get_protect_object(self):
        return self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_OBJECT, {})

    def get_deploy_type(self):
        return self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_ENV, {}) \
            .get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaJsonConstant.DB_DEPLOY_TYPE, "")

    def get_protectdb_auth_type(self):
        db_type = self.get_backup_db_type()
        if db_type == SaphanaConst.SYSTEM_DATABASE:
            type_env = f"{SaphanaJsonConstant.JOB}_{SaphanaJsonConstant.PROTECT_ENV}_{SaphanaJsonConstant.AUTH}" \
                   f"_{SaphanaJsonConstant.AUTH_TYPE}_{self._pid}"
        else:
            type_env = f"{SaphanaJsonConstant.JOB}_{SaphanaJsonConstant.PROTECT_OBJECT}_{SaphanaJsonConstant.AUTH}" \
                   f"_{SaphanaJsonConstant.AUTH_TYPE}_{self._pid}"
        return get_env_variable(type_env).strip("\n")

    def get_systemdb_auth_type(self):
        type_env = f"{SaphanaJsonConstant.JOB}_{SaphanaJsonConstant.PROTECT_ENV}_{SaphanaJsonConstant.AUTH}" \
                   f"_{SaphanaJsonConstant.AUTH_TYPE}_{self._pid}"
        return get_env_variable(type_env).strip("\n")

    def get_instance_user_store(self):
        return self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_ENV, {}) \
            .get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaJsonConstant.DEPLOY_TYPE, "")

    def get_log_backup_path(self):
        log_ext_info = json.loads(self._json_param.get(SaphanaJsonConstant.JOB, {}).
                                  get(SaphanaJsonConstant.PROTECT_ENV, {}).get(SaphanaJsonConstant.EXTEND_INFO, {}).
                                  get(SaphanaJsonConstant.LOG_BACKUP_EXT_INFO, "{}"))
        if not log_ext_info:
            return ""
        return log_ext_info.get(SaphanaJsonConstant.LOG_BACKUP_PATH, "")

    def get_log_repo(self):
        repositories = self.get_all_repositories()
        if not repositories:
            return ""
        for repository in repositories:
            if repository.get(SaphanaJsonConstant.REPOSITORY_TYPE, "") != RepositoryDataTypeEnum.LOG_REPOSITORY:
                continue
            return repository
        return ""

    def get_resource_id(self):
        return self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant.PROTECT_OBJECT, {}). \
            get(SaphanaJsonConstant.ID, {})


class SaphanaCopyInfoParam:

    @staticmethod
    def get_db_info(param):
        return param.get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaMetadataKey.DB_INFO, {})

    @staticmethod
    def get_system_attr(param):
        return param.get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaMetadataKey.MULTI_TENANT_SYSTEM, None)

    @staticmethod
    def get_last_backup_hostname(param):
        return param.get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaMetadataKey.BACKUP_HOSTNAME, 0)
